Golang 基础语法 (1)

变量的声明

在 go 的包中,一个变量或者方法函数或者常量以大写字母开头,可以被包外看见使用
既大写的包变量或者包方法或者包常量是可以导出的
小写的包变量和包方法还有包常量只能在包内访问

  • 以下定义方法无论是函数体外还是内都可以

//定义一个变量,名称为 "numberOfTimes",类型为 "int"
var numberOfTimes int
//定义三个变量,类型为 “int"
var var1, var2, var3 int
//定义一个变量,名称为 "numberOfTimes",类型为 "int",值为 "3"
var numberOfTimes int = 3
//定义三个类型为 "int" 的变量,并且初始化它们的值
var var1, var2, var3 int = 1, 2, 3
  • 变量声明快捷方式(只能在函数或者方法内)

package main

//✅
var foo string
//❌
foo := "test"
func main(){
    var bar int
    foo1 := 10
    //v1 v2 v3可以是任意类型,编译器会自动确认数据类型
    vname1, vname2, vname3 := v1, v2, v3
    
    //下面的 var1 := 11会报错,因为变量 var1已经被定义,不能重复定义
    var var1 int = 10
    var1 := 11
    //下面正确,只是给 var2重新赋值
    var var2 int = 10
    var2 = 12
}
  • 特殊变量(弃用变量或者导入包不使用)

go 语言中没有使用的包或者变量,会导致编译失败

//"net/http" 包导入不使用,如果包里面有 init 方法,只执行 init 方法
import(
    "fmt"
    _ "net/http"
)
func main(){
    //函数 divede 返回值第一个放弃不使用
    _, remainder := divide(10, 3)
}
  • 分组定义

//导入包
import(
    "fmt"
    "os"
)
//常量定义
const(
    i = 100
    pi = 3.1415
    prefix = "Go_"
)
//变量
var(
    i int
    pi float32
    prefx string
)
//结构体
type(
    people struct{
        name string
        age int
    }
    animal struct{
        name string
        leg int
    }
)
  • 关键字 iota

const(
    x = iota // x == 0
    y = iota // y == 1
    z = iota // z == 2
    w // 省略 iota ,w == 3
)
const(
    a = iota // a == 0
    b = 10
    c // c == 1
    d // d == 2
)
const v = iota //v ==0
const(
    e, f, g = iota, iota, iota // e==0, f==0, g==0 因为在同一行
)

基本数据类型的特性

  • 布尔类型

    • bool 表示布尔类型

    • bool 的值 只有 true 和 false 且默认值为 false

    • bool 的值不能转换为数字

  • 数字类型

    • 整形 int

      • 整形分为有符号 int 和无符号 uint,它们具有相同的长度,具体长度取决于操作系统,32位操作系统为32位,64位操作系统为64

      • go语言也定义了 rune,byte,int(8,16,32,64),uint(8,16,32,64)

      • rune 是 int32的别名,byte 是 uint8的别名

      • go 语言不允许不同整型赋值

      var a int8 = 10
      var b int32 = 10
      //编译报错
      c := a+b
    • 浮点型

      • 只有 float32 和 float64, 没有 float

    • 复数 complex

  • 字符串 string

    • go 使用 UTF-8 编码

    • "" 或者 `` 包裹起来的就是字符串

    • string 不允许改变值

    • 改变一个字符串的方法

    s := "hello"
    c := []byte(s)
    c[0] = 'c'
    s2 := string(c)
    //思考下面的代码 s1的地址是固定不变的还是会变?
    //s1 的地址不会改变,string 底层是一个结构体,两个字段
    //其中一个是指向数据的指针
    //另外一个是数据的长度
    s1 := "hello"
    s1 = "sea"
    s1 = "aa" + s1[1:]
    • 使用 "+" 连接两个字符串

    • `` 多行字符串,不会转义任何字符

    m := `hello
    world`

错误类型Error types

go 没有异常处理机制,内置 error 类型,用于处理 errors
go 要求我们要么显式处理错误要么忽略

array, slice, map

  • array 定义

var arr [n]type
a := [3]int{1, 2, 3}
//... 自动识别数组长度
a := [...]int{1,3,3}
d := [2][2]int{[2]int{0,0}, [2]int{2,2}}
d1 := [2][2]int{{1,1}, {22,22}}
  • slice 定义

var fslice []int
slice := []byte{'a', 'c', 'd'}
  • slice 操作

a := []int{1,2,3,5}
b := a[1:] // b 为 2,3,5 但是 a  b 共享底层数据结构,修改 a 或者 b , a和 b 都会改变
b := a[:2] // b 为 1, 2
  • 内置函数

    • len 获取 slice 长度

    • cap 获取 slice 最大容量

    • append 追加一个或者多个元素到 slice, 返回 slice

    • copy 复制一个 slice 到另外一个,返回 copy的元素个数

  • map - 类似于 Ptyon 里面的字典 key-value

    • map 不是有序的,每次打印输出结果顺序不一样,使用 key 去获取 value

    • map 没有固定长度,和 slice 一样是引用类型

    • len 函数可以用在 map上,返回 map 现在包含多少个 key

    • map 可以很容易根据 key 修改 value

    • delete 可以删除 map 中指定key 的元素

slice 的索引只能是 int,map 的索引可以是任何你想要的类型

numbers := make(map[string]int)
numbers["one"] = 1

make new 区别

  • make 给内置类型分配内存,并且初始化它们,返回非零值

    • map

    • slice

    • channel

  • new(T) 返回零值

控制结构和函数

  • if 不需要括号

if test {
}
//分号隔开,赋值
if x := len(slice); x >0 {
}
  • goto

func my(){
    i := 0
Here:   //label goto
    i++
    goto Here //跳转到 Here
}
  • for 可替代 while,do-while

    • break continue

  • switch

    • case 的值可以有多个 逗号隔开

    • 只执行匹配的 case 不需要 break

    • default 如果没有匹配的执行

  • func 定义函数

    • 函数有0-多个参数,参数名称在参数类型前

    • 函数可以返回多个值或者不返回值

    • 多变参数 ...

    • go 函数参数本质都是传值

    • 函数可以被当做值和参数类型

func funcName(p1 type1, p2 type2)(returnType1, returnType2{
    return a, b
}
func varFunc(arg1 ...int){
}
  • defer 延迟执行,先进后出 FILO

  • panic & recover

  • main & init 函数

    • main 包的 main 函数,是程序入口

    • 每个包可以有多个 init 函数,在 impprt 的时候执行,用于做一些初始化操作,包里面每个文件就只能一个 init 函数了

  • import 导入包

    • . 操作符,调用的还是可以忽略掉包名

    • 别名

    • _ 只导入不使用

import(
    . ”fmt" //忽略包名
    o "os"  //别名
    _ "net/http"    //导入包执行 init 方法不使用
)

未完待续


luxixing
3k 声望119 粉丝

最近在学习大数据相关知识